from faker import Faker
import random
from datetime import datetime, timedelta
from data_mock.utils import FileUtil, MysqlUtils_AI

fake = Faker('zh_CN')

# ========== 癌症相关配置 ==========
CANCER_TYPES = {
    'C34.90': {'name': '肺恶性肿瘤', 'symptoms': ['咳嗽', '咯血', '胸痛', '呼吸困难']},
    'C16.9': {'name': '胃恶性肿瘤', 'symptoms': ['上腹痛', '恶心呕吐', '黑便', '食欲减退']},
    'C18.9': {'name': '结肠恶性肿瘤', 'symptoms': ['腹痛', '便血', '排便习惯改变', '体重下降']},
    'C50.919': {'name': '乳腺恶性肿瘤', 'symptoms': ['乳房肿块', '乳头溢液', '皮肤凹陷', '腋窝淋巴结肿大']},
    'C61': {'name': '前列腺恶性肿瘤', 'symptoms': ['排尿困难', '尿频', '血尿', '骨盆疼痛']}
}

COMMON_DIAGNOSES = {
    'I10': '高血压',
    'E11.9': '2型糖尿病',
    'E78.5': '高脂血症',
    'J18.9': '肺炎',
    'K21.9': '胃食管反流病'
}

SURGERY_INFO = {
    '肺恶性肿瘤': {
        'procedures': [
            {'code': '32.2900x001', 'name': '胸腔镜下肺叶切除术', 'level': '四级', 'approach': '胸腔镜'},
            {'code': '32.4901', 'name': '肺楔形切除术', 'level': '三级', 'approach': '开胸'}
        ],
        'dept': '胸外科',
        'incision': 'Ⅰ类切口'
    },
    '胃恶性肿瘤': {
        'procedures': [
            {'code': '43.5', 'name': '胃大部切除术', 'level': '三级', 'approach': '开腹'},
            {'code': '43.9900x003', 'name': '腹腔镜下胃癌根治术', 'level': '四级', 'approach': '腹腔镜'}
        ],
        'dept': '胃肠外科',
        'incision': 'Ⅱ类切口'
    },
    '结肠恶性肿瘤': {
        'procedures': [
            {'code': '45.7301', 'name': '结肠癌根治术', 'level': '三级', 'approach': '开腹'},
            {'code': '45.8100x001', 'name': '腹腔镜下结肠癌根治术', 'level': '四级', 'approach': '腹腔镜'}
        ],
        'dept': '胃肠外科',
        'incision': 'Ⅱ类切口'
    },
    '乳腺恶性肿瘤': {
        'procedures': [
            {'code': '85.2300x001', 'name': '乳腺癌改良根治术', 'level': '三级', 'approach': '开放手术'},
            {'code': '85.2100x001', 'name': '乳腺象限切除术', 'level': '三级', 'approach': '开放手术'}
        ],
        'dept': '乳腺外科',
        'incision': 'Ⅰ类切口'
    },
    '前列腺恶性肿瘤': {
        'procedures': [
            {'code': '60.5', 'name': '前列腺癌根治术', 'level': '四级', 'approach': '腹腔镜'},
            {'code': '60.2100x001', 'name': '经尿道前列腺切除术', 'level': '三级', 'approach': '内镜'}
        ],
        'dept': '泌尿外科',
        'incision': 'Ⅰ类切口'
    }
}

ANESTHESIA_TYPES = ['全身麻醉', '硬膜外麻醉', '腰硬联合麻醉', '局部麻醉']
BLOOD_TYPES = ['A', 'B', 'AB', 'O']
BLOOD_COMPONENTS = ['全血', '红细胞悬液', '血浆', '血小板']


# ========== 生成函数 ==========
def generate_surgery_records():
    sql_statements = []
    record_sn_counter = 30001  # 记录流水号计数器

    # 生成30天的数据
    for day in generate_day_range("2025-08-01", "2025-08-30"):
        records_per_day = 4 if datetime.strptime(day, "%Y-%m-%d").day % 2 else 6

        for i in range(records_per_day):
            # 选择随机癌症类型
            cancer_code, cancer_info = random.choice(list(CANCER_TYPES.items()))
            surgery_info = SURGERY_INFO[cancer_info['name']]
            procedure = random.choice(surgery_info['procedures'])

            # 生成患者基本信息
            patient_id = f"PT{random.randint(1000, 9999)}"
            visit_sn = f"VIS{random.randint(1000, 9999)}"
            record_sn = f"SUR{record_sn_counter}"
            record_sn_counter += 1

            # 生成手术时间（手术时长1-4小时）
            surgery_date = fake.date_time_between(
                start_date=datetime.strptime(day, "%Y-%m-%d"),
                end_date=datetime.strptime(day, "%Y-%m-%d") + timedelta(days=1)
            )
            surgery_duration = random.randint(1, 4)
            start_time = surgery_date
            end_time = surgery_date + timedelta(hours=surgery_duration)

            # 生成麻醉时间（提前30-60分钟开始）
            anesthesia_start = surgery_date - timedelta(minutes=random.randint(30, 60))
            anesthesia_end = end_time + timedelta(minutes=random.randint(10, 30))

            # 生成诊断信息
            diagnoses = generate_diagnoses(cancer_code, cancer_info['name'])

            # 生成输血信息
            blood_trans = generate_blood_transfusion()

            # 构建数据字典
            data = {
                'patient_id': patient_id,
                'visit_sn': visit_sn,
                'medical_record_no': f"MR{random.randint(100000, 999999)}",
                'inpatient_no': f"IP{random.randint(100000, 999999)}",
                'record_sn': record_sn,
                'record_datetime': end_time.strftime('%Y-%m-%d %H:%M:%S'),
                'surgeon_no': f"DOC{random.randint(1000, 9999)}",
                'technical_title': random.choice(['主任医师', '副主任医师', '主治医师']),
                'job_title': random.choice(['科主任', '副主任', '主治医师', '住院医师']),
                'executive_dept_name': surgery_info['dept'],
                'surgery_code': procedure['code'],
                'surgery_name': procedure['name'],
                'start_datetime': start_time.strftime('%Y-%m-%d %H:%M:%S'),
                'finish_datetime': end_time.strftime('%Y-%m-%d %H:%M:%S'),
                'incision_type': surgery_info['incision'],
                'surgery_level': procedure['level'],
                'surgical_approach': procedure['approach'],
                'procedures_description': generate_procedure_description(cancer_info['name'], procedure['name']),
                'anesthesia_type': random.choice(ANESTHESIA_TYPES),
                'asa_physical_status': str(random.randint(1, 3)),
                'anesthesia_start_time': anesthesia_start.strftime('%Y-%m-%d %H:%M:%S'),
                'anesthesia_end_time': anesthesia_end.strftime('%Y-%m-%d %H:%M:%S'),
                'blood_trans_abo': random.choice(BLOOD_TYPES),
                'blood_trans_rh': random.choice(['阳性', '阴性']),
                'blood_loss_volume': str(random.randint(100, 800)),
                'presurgery_maindiag_code1': diagnoses[0]['code'],
                'presurgery_maindiag_name1': diagnoses[0]['name'],
                'presurgery_diag_code2': diagnoses[1]['code'] if len(diagnoses) > 1 else None,
                'presurgery_diag_name2': diagnoses[1]['name'] if len(diagnoses) > 1 else None,
                'presurgery_diag_code3': diagnoses[2]['code'] if len(diagnoses) > 2 else None,
                'presurgery_diag_name3': diagnoses[2]['name'] if len(diagnoses) > 2 else None,
                'intrasurgery_maindiag_code1': diagnoses[0]['code'],
                'intrasurgery_maindiag_name1': diagnoses[0]['name'],
                'postsurgery_maindiag_code1': diagnoses[0]['code'],
                'postsurgery_maindiag_name1': diagnoses[0]['name'],
                'record_status': 1,
                'yy_upload_status': 0,
                'yy_etl_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'yy_batch_time': day,
                'yy_record_batch_id': f"BATCH{day}_{i}"
            }

            # 添加输血信息
            if blood_trans:
                data.update({
                    'blood_trans_component': blood_trans['component'],
                    'blood_trans_volume': blood_trans['volume'],
                    'blood_trans_component1': blood_trans.get('component1'),
                    'blood_trans_volume1': blood_trans.get('volume1')
                })

            sql = generate_sql('b08_1', data)
            sql_statements.append(sql)

    return sql_statements


# ========== 文书内容生成函数 ==========
def generate_procedure_description(cancer_name, procedure_name):
    descriptions = {
        '肺恶性肿瘤': [
            f"患者取侧卧位，常规消毒铺巾，行{procedure_name}。术中见肿瘤位于右肺上叶，大小约{random.randint(2, 5)}cm×{random.randint(2, 5)}cm，与周围组织分界尚清。完整切除肿瘤及周围部分肺组织，清扫淋巴结。手术过程顺利，出血约{random.randint(100, 500)}ml。",
            f"全麻成功后，患者取侧卧位，常规消毒铺巾。行{procedure_name}，术中探查见肿瘤位于左肺下叶，大小约{random.randint(2, 5)}cm×{random.randint(2, 5)}cm，质硬，与胸膜轻度粘连。锐性分离粘连，完整切除肿瘤，清扫纵隔淋巴结。手术顺利，出血约{random.randint(100, 500)}ml。"
        ],
        '胃恶性肿瘤': [
            f"患者平卧位，常规消毒铺巾。行{procedure_name}，术中探查见肿瘤位于胃窦部，大小约{random.randint(3, 6)}cm×{random.randint(3, 6)}cm，侵及浆膜层。游离胃大弯、小弯，切断十二指肠，行胃大部切除，BillrothⅡ式吻合。手术顺利，出血约{random.randint(200, 800)}ml。",
            f"全麻成功后，患者平卧位，常规消毒铺巾。行{procedure_name}，术中见肿瘤位于胃体部，大小约{random.randint(3, 6)}cm×{random.randint(3, 6)}cm，与胰腺轻度粘连。锐性分离粘连，切除远端胃，行胃空肠吻合。手术顺利，出血约{random.randint(200, 800)}ml。"
        ],
        '结肠恶性肿瘤': [
            f"患者平卧位，常规消毒铺巾。行{procedure_name}，术中探查见肿瘤位于降结肠，大小约{random.randint(3, 6)}cm×{random.randint(3, 6)}cm，侵及浆膜层。游离结肠系膜，切除肿瘤及周围肠管约{random.randint(10, 20)}cm，行端端吻合。手术顺利，出血约{random.randint(200, 600)}ml。",
            f"全麻成功后，患者平卧位，常规消毒铺巾。行{procedure_name}，术中见肿瘤位于升结肠，大小约{random.randint(3, 6)}cm×{random.randint(3, 6)}cm，与侧腹壁轻度粘连。锐性分离粘连，切除右半结肠，行回肠横结肠吻合。手术顺利，出血约{random.randint(200, 600)}ml。"
        ],
        '乳腺恶性肿瘤': [
            f"患者平卧位，常规消毒铺巾。行{procedure_name}，术中见肿瘤位于左乳外上象限，大小约{random.randint(2, 5)}cm×{random.randint(2, 5)}cm，质硬，活动度差。完整切除肿瘤及周围乳腺组织，清扫腋窝淋巴结。手术顺利，出血约{random.randint(100, 400)}ml。",
            f"全麻成功后，患者平卧位，常规消毒铺巾。行{procedure_name}，术中探查见肿瘤位于右乳内上象限，大小约{random.randint(2, 5)}cm×{random.randint(2, 5)}cm，与胸大肌筋膜轻度粘连。锐性分离粘连，完整切除肿瘤及周围组织，清扫腋窝淋巴结。手术顺利，出血约{random.randint(100, 400)}ml。"
        ],
        '前列腺恶性肿瘤': [
            f"患者截石位，常规消毒铺巾。行{procedure_name}，术中见前列腺体积增大，质硬，与周围组织分界欠清。锐性分离前列腺包膜，完整切除前列腺及精囊，行膀胱尿道吻合。手术顺利，出血约{random.randint(300, 800)}ml。",
            f"全麻成功后，患者截石位，常规消毒铺巾。行{procedure_name}，术中探查见前列腺质地坚硬，与直肠前壁轻度粘连。锐性分离粘连，完整切除前列腺，清扫盆腔淋巴结。手术顺利，出血约{random.randint(300, 800)}ml。"
        ]
    }
    return random.choice(descriptions[cancer_name])


def generate_diagnoses(primary_code, primary_name):
    diagnoses = [{'code': primary_code, 'name': primary_name}]
    # 添加1-2个合并症
    for _ in range(random.randint(1, 2)):
        code, name = random.choice(list(COMMON_DIAGNOSES.items()))
        diagnoses.append({'code': code, 'name': name})
    return diagnoses


def generate_blood_transfusion():
    # 30%的概率需要输血
    if random.random() < 0.3:
        component = random.choice(BLOOD_COMPONENTS)
        volume = str(random.randint(200, 600))
        if random.random() < 0.2:  # 20%的概率需要输两种成分
            component1 = random.choice([c for c in BLOOD_COMPONENTS if c != component])
            volume1 = str(random.randint(100, 400))
            return {
                'component': component,
                'volume': volume,
                'component1': component1,
                'volume1': volume1
            }
        else:
            return {
                'component': component,
                'volume': volume
            }
    return None


# ========== 辅助函数 ==========
def generate_day_range(start_date, end_date):
    start = datetime.strptime(start_date, "%Y-%m-%d")
    end = datetime.strptime(end_date, "%Y-%m-%d")
    delta = end - start
    return [(start + timedelta(days=i)).strftime("%Y-%m-%d") for i in range(delta.days + 1)]


def generate_sql(table, data):
    columns = []
    values = []
    for k, v in data.items():
        columns.append(f"`{k}`")
        if v is None:
            values.append("NULL")
        elif isinstance(v, (int, float)):
            values.append(str(v))
        else:
            escaped_value = str(v).replace("'", "''")
            values.append(f"'{escaped_value}'")
    return f"INSERT INTO `{table}` ({', '.join(columns)}) VALUES ({', '.join(values)});"


# ========== 执行生成 ==========
if __name__ == "__main__":
    print("开始生成手术记录数据...")
    records = generate_surgery_records()
    # 写入数据库
    MysqlUtils_AI.insert_data_to_hub(records, 'b08_1')
    print(f"成功生成{len(records)}条手术记录数据")